﻿namespace CatFax.Entities
{
    using System.Data.Services.Client;
    using System.Linq;
    using Microsoft.Samples.ServiceHosting.StorageClient;

    /// <summary>
    /// Azure tables service context for AuditRowIndexes
    /// </summary>
    public class AuditRowIndexEntityDataServiceContext : TableStorageDataServiceContext
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="AuditRowIndexEntityDataServiceContext"/> class.
        /// </summary>
        /// <param name="accountInfo">
        /// Azure tables account info
        /// </param>
        public AuditRowIndexEntityDataServiceContext(StorageAccountInfo accountInfo)
                : base(accountInfo)
        {
        }

        /// <summary>
        /// Gets all rows in azure table
        /// </summary>
        public IQueryable<AuditRowIndexEntity> AuditRowIndexes
        {
            get
            {
                return CreateQuery<AuditRowIndexEntity>("AuditRowIndexes");
            }
        }

        /// <summary>
        /// Adds row to azure table
        /// </summary>
        /// <param name="rowKey">
        /// The row key.
        /// </param>
        /// <param name="lastSeq">
        /// The last seq.
        /// </param>
        /// <param name="rowPartition">
        /// The row partition.
        /// </param>
        public void AddAuditRowIndexEntity(string rowKey, int lastSeq, string rowPartition)
        {
            this.AddObject("AuditRowIndexes", new AuditRowIndexEntity { RowKey = rowKey, LastSeq = lastSeq, RowPartition = rowPartition });
            this.SaveChanges();
        }

        /// <summary>
        /// Check if row exists in Azure table
        /// </summary>
        /// <param name="rowKey">
        /// The row key.
        /// </param>
        /// <returns>
        /// True if exists
        /// </returns>
        public bool Exists(string rowKey)
        {
            try
            {
                AuditRowIndexEntity foundAuditRowIndex =
                   (from auditRowIndexEntity in this.CreateQuery<AuditRowIndexEntity>("AuditRowIndexes")
                    where auditRowIndexEntity.PartitionKey == "Index"
                       && auditRowIndexEntity.RowKey == rowKey
                    select auditRowIndexEntity).FirstOrDefault();
            }
            catch (DataServiceQueryException ex)
            {
                return false; // Not interested in exception - assume that row does not exist
            }

            return true;
        }

        /// <summary>
        /// Get next sequence number for a particualr row
        /// </summary>
        /// <param name="rowKey">
        /// The row key.
        /// </param>
        /// <param name="rowPartition">
        /// The row partition.
        /// </param>
        /// <returns>
        /// Next sequence number
        /// </returns>
        public int NextSeqForRow(string rowKey, string rowPartition)
        {
            int nextSeq = 1;
            AuditRowIndexEntity foundAuditRowIndex = null;
            foundAuditRowIndex =
               (from auditRowIndexEntity in this.CreateQuery<AuditRowIndexEntity>("AuditRowIndexes")
                where auditRowIndexEntity.PartitionKey == "Index"
                   && auditRowIndexEntity.RowKey == rowKey
                select auditRowIndexEntity).FirstOrDefault();
            foundAuditRowIndex.LastSeq++;
            UpdateObject(foundAuditRowIndex);
            SaveChanges();
            nextSeq = foundAuditRowIndex.LastSeq;
            return nextSeq;
        }

        /// <summary>
        /// Returns a row (that must exist)
        /// </summary>
        /// <param name="rowKey">
        /// The row key.
        /// </param>
        /// <returns>
        /// Found row
        /// </returns>
        public AuditRowIndexEntity GetSingleRow(string rowKey)
        {
            return (from auditRowIndexEntity in this.CreateQuery<AuditRowIndexEntity>("AuditRowIndexes")
                where auditRowIndexEntity.PartitionKey == "Index"
                   && auditRowIndexEntity.RowKey == rowKey
                select auditRowIndexEntity).FirstOrDefault();
        }
    }
}
